Return <4GB memory back to Xen when destroying a PAE pgdir.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 24 Feb 2006 07:49:32 +0000 (08:49 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 24 Feb 2006 07:49:32 +0000 (08:49 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c

index 783ea6396434a73b8d1042e35a50dbdeba64e52b..2ab318c251e716310c9602864a999c6fdf05b242 100644 (file)
@@ -759,7 +759,7 @@ void __init pgtable_cache_init(void)
 #endif
                                0,
                                pgd_ctor,
-                               PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
+                               pgd_dtor);
        if (!pgd_cache)
                panic("pgtable_cache_init(): Cannot create pgd cache");
 }
index 869d43ef896e696814bc9bfb35612b55a00dc70a..c2d97b5b2d8871adf443fb57e6408cb50fa7b730 100644 (file)
@@ -320,16 +320,20 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
        }
 }
 
-/* never called when PTRS_PER_PMD > 1 */
 void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
 {
        unsigned long flags; /* can be called from interrupt context */
 
-       spin_lock_irqsave(&pgd_lock, flags);
-       pgd_list_del(pgd);
-       spin_unlock_irqrestore(&pgd_lock, flags);
+       if (PTRS_PER_PMD > 1) {
+               if (!xen_feature(XENFEAT_pae_pgdir_above_4gb))
+                       xen_destroy_contiguous_region((unsigned long)pgd, 0);
+       } else {
+               spin_lock_irqsave(&pgd_lock, flags);
+               pgd_list_del(pgd);
+               spin_unlock_irqrestore(&pgd_lock, flags);
 
-       pgd_test_and_unpin(pgd);
+               pgd_test_and_unpin(pgd);
+       }
 }
 
 pgd_t *pgd_alloc(struct mm_struct *mm)